package com.gopay.bis.nucc.common.util;

import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.exception.GopayException;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @description: 发送请求类
 * @author: zhoutong
 * @datetime: 2017/08/21 10:44
 * @version: 1.0.0
 */
public class NuccHttpClientUtil extends HttpClientConnManager {
    /**
     * 日志
     */
    private static Logger logger = LoggerFactory.getLogger(NuccHttpClientUtil.class);
    /**
     * 发送 SSL POST 请求（HTTPS）
     *
     * @param url      请求url
     * @param reqXml   请求报文
     * @param paramMap 请求参数map
     * @return String
     * @throws GopayException 内部异常
     */
    public String send(String url, String reqXml, Map<String, String> paramMap) throws GopayException {
        CloseableHttpClient httpClient = getHttpClient();

        //创建HttpPost,加载url
        HttpPost httpPost = new HttpPost(url);

        CloseableHttpResponse response = null;

        String httpStr = "";

        try {
            httpPost.setConfig(requestConfig);
            //设置http头部域
            httpPost.setHeader("Content-Type", "application/xml;charset=utf-8");
            for (String key : paramMap.keySet()) {
                logger.info("http头部域：key=" + key + ";value=" + paramMap.get(key));
                httpPost.setHeader(key, paramMap.get(key));
            }
            //设置http体和字符编码
            httpPost.setEntity(new StringEntity(reqXml, SEND_ENCODING));

            //通讯
            logger.info("http通讯开始，URL为:" + url);
            logger.info("通讯上送报文:" + reqXml);
            response = httpClient.execute(httpPost);
            //获取通讯状态码
            int statusCode = response.getStatusLine().getStatusCode();
            logger.info("http通讯结束，通讯状态码为:" + statusCode);
            //如果返回非200，抛出通讯异常错误
            if (HttpStatus.SC_OK != statusCode) {
                logger.error("通讯异常，通讯状态码非200，而为" + statusCode);
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E6122);
            }

            HttpEntity entity = response.getEntity();
            //如果返回内容为空，抛出通讯异常错误
            if (null == entity) {
                logger.error("通讯异常，返回为空");
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E6123);
            }

            httpStr = EntityUtils.toString(entity, SEND_ENCODING);
            logger.info("通讯返回报文:" + httpStr);
            if (StringUtils.isBlank(httpStr)) {
                logger.error("通讯异常，返回报文为空");
                throw new GopayException(ProcCodeConstants.PROC_CODE_100E6123);
            }
        } catch (ConnectionPoolTimeoutException | SocketTimeoutException e) {
            //超时，抛出超时异常
            logger.error("通讯超时",e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6125);
        } catch (Exception e) {
            //其他异常，抛出通讯异常错误
            logger.error("通讯异常",e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E6124);
        } finally {
            if (null != response) {
                try {
                    //销毁
                    EntityUtils.consume(response.getEntity());
                } catch (IOException e) {
                    logger.error(e.getMessage());
                }
            }
        }
        return httpStr;
    }
}
